//
//  String+KYExtension.swift
//  KFManager
//
//  Created by kingly on 2016/11/15.
//  Copyright © 2016年 kingly inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. All rights reserved.
//

import Foundation

let whitespaceAndNewlineChars: [Character] = ["\n", "\r", "\t", " "]

extension String {

    /// 时间戳字符串转为时间字符串
    ///
    /// - Returns: 时间字符串
    func ky_timeStampToString() -> String
    {
        let string = NSString(string: self)
        let timeSta: TimeInterval = string.doubleValue
        let dfmatter = DateFormatter()
        dfmatter.dateFormat = "yyyy年MM月dd日"
        let date = Date(timeIntervalSince1970: timeSta)
        return dfmatter.string(from: date)
    }

    /// 时间字符串转为时间戳
    ///
    /// - Returns: 时间戳字符串
    func ky_stringToTimeStamp() -> String
    {
        let dfmatter = DateFormatter()
        dfmatter.dateFormat = "yyyy年MM月dd日"
        let date = dfmatter.date(from: self)
        let dateStamp: TimeInterval = date!.timeIntervalSince1970
        let dateSt:Int = Int(dateStamp)
        return String(dateSt)
    }
  
   /// 时间字符串转为时间戳
   ///
   /// - Returns: 时间戳字符串
   func ky_stringToTimeStamp(dateFormat: String) -> String
   {
    let dfmatter = DateFormatter()
    dfmatter.dateFormat = dateFormat
    let date = dfmatter.date(from: self)
    let dateStamp: TimeInterval = date!.timeIntervalSince1970
    let dateSt:Int = Int(dateStamp)
    return String(dateSt)
   }


//    /// 从当前的字符串中，提取链接和文本
//    /// Swift中提供了’元祖‘，同时返回多个值
//    /// OC 中可以返回字典，或者自定义对象，也可以用指针的指针
//    func ky_href() -> ((link: String, text: String))? {
//        //匹配方案
//        let pattern = "<a href=\"(.*?)\".*?>(.*?)</a>"
//        // 创建正则表达式
//        guard let regx = try? NSRegularExpression(pattern: pattern, options: []),
//            let result =  regx.firstMatch(in: self, options: [], range: NSRange(location: 0, length:  chars.count))else {
//                return nil
//        }
//        //获取结果
//      let link = (self as NSString).substring(with: result.range(at: 1))
//      let text = (self as NSString).substring(with: result.range(at: 2))
//
//        return(link,text)
//    }
//
  
  
  
    
    /// 获取字符串的长度 
    ///
    /// - Returns: 字符串的长度 
    func ky_stringLength() -> Int64 {
    
       return Int64(self.lengthOfBytes(using: String.Encoding.utf8))
    }
    /// ky_trim: trim the \n and blank of leading and trailing
    ///
    /// - Returns: 去除两端的空格
    func ky_trim() -> String {
        return trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines).trimmingCharacters(in: NSCharacterSet.whitespaces)
    }
    
    /// 获取字符串返回int值
    ///
    /// - Returns: 字符串返回int值
    func ky_intValue() -> Int? {
        let scanner = Scanner(string: self)
        scanner.scanUpToCharacters(from: NSCharacterSet.decimalDigits, into: nil)
        var intValue = 0
        if scanner.scanInt(&intValue) {
            return intValue
        }
        return nil
    }

    /// 获取字符串返回字符串值
    ///
    /// - Returns: 字符串返回字符串值
    func ky_stringValue() -> String? {
        let scanner = Scanner(string: self)
        var s: NSString? = ""
        if scanner.scanString(self, into: &s) {
          let stringValue = s as String?
            return stringValue
        }
        return nil
    }
  
    /// 字符串转NSData
    ///
    /// - Returns: 字符串转NSData的NSData值
    func ky_NSData() -> NSData {
        return self.data(using: String.Encoding.utf8)! as NSData
    }

    /// 时间字符串转NSDate
    ///
    /// - Returns: 返回时间字符串转NSDate
    func ky_NSDate() -> NSDate {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
        return dateFormatter.date(from: self)! as NSDate
    }
  
  /// 是否是手机号码
  ///
  /// - Returns: YES 是手机号
  func isTelNumber()->Bool {
    let mobile = "^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$"
      let CM = "^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$"
      let CU = "^1(3[0-2]|5[256]|8[56])\\d{8}$"
      let CT = "^1((33|53|8[09])[0-9]|349)\\d{7}$"
      let regextestmobile = NSPredicate(format: "SELF MATCHES %@",mobile)
      let regextestcm = NSPredicate(format: "SELF MATCHES %@",CM )
      let regextestcu = NSPredicate(format: "SELF MATCHES %@" ,CU)
      let regextestct = NSPredicate(format: "SELF MATCHES %@" ,CT)
    if ((regextestmobile.evaluate(with: self) == true) || (regextestcm.evaluate(with: self) == true) || (regextestct.evaluate(with: self) == true) || (regextestcu.evaluate(with: self) == true)) {
        return true
      } else {
        return false
      }
  }
  
  /// 是否用户名，长度为2～20位字母，数字或符号组成，以字母开头
  ///
  /// - Returns: 匹配用户名
  func ky_isUserName()-> Bool {
     let username = "^[a-zA-Z]{1}[a-zA-Z0-9.\\-_]{1,19}$"
     let regextestusername = NSPredicate(format: "SELF MATCHES %@",username)
     if (regextestusername.evaluate(with: self) == true) {
      return true
     }
    return false
  }

  
  /// 匹配汉子和字母数字
  func ky_isChineseName()-> Bool {
    let username = "^[\\u4e00-\\u9fa5a-zA-Z0-9]+$"
    let regextestusername = NSPredicate(format: "SELF MATCHES %@",username)
    if (regextestusername.evaluate(with: self) == true) {
      return true
    }
    return false
  }
  
   /// 是否是数字
   ///
   /// - Returns: YES 是数字 NO 不是数字
   func isPurnInt() -> Bool {
    
    let scan: Scanner = Scanner(string: self)
    
    var val:Int = 0
    
    return scan.scanInt(&val) && scan.isAtEnd
    
   }
  
  /// nsRange
  ///
  /// - Parameter range: nsRange
  /// - Returns: nsRange
  func nsRange(from range: Range<String.Index>) -> NSRange? {
    
    let utf16view = self.utf16
    if let from = range.lowerBound.samePosition(in: utf16view), let to = range.upperBound.samePosition(in: utf16view) {
      
      return NSMakeRange(utf16view.distance(from: utf16view.startIndex, to: from), utf16view.distance(from: from, to: to))
      
    }
    return nil
    
  }
  
  ///把 x 数字精确到小数点后第 p 位，不足 p 位补 0，然后四舍五入
  func preciseDecimal(p : Int) -> String {
    //        为了安全要判空
    if (Double(self) != nil) {
      //         四舍五入
      let decimalNumberHandle : NSDecimalNumberHandler = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode(rawValue: 0)!, scale: Int16(p), raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)
      let decimaleNumber : NSDecimalNumber = NSDecimalNumber(value: Double(self)!)
      let resultNumber : NSDecimalNumber = decimaleNumber.rounding(accordingToBehavior: decimalNumberHandle)
      //          生成需要精确的小数点格式，
      //          比如精确到小数点第3位，格式为“0.000”；精确到小数点第4位，格式为“0.0000”；
      //          也就是说精确到第几位，小数点后面就有几个“0”
      var formatterString : String = "0."
      let count : Int = (p < 0 ? 0 : p)
      for _ in 0 ..< count {
        formatterString.append("0")
      }
      let formatter : NumberFormatter = NumberFormatter()
      //      设置生成好的格式，NSNumberFormatter 对象会按精确度自动四舍五入
      formatter.positiveFormat = formatterString
      //          然后把这个number 对象格式化成我们需要的格式，
      //          最后以string 类型返回结果。
      return formatter.string(from: resultNumber)!
    }
    return "0"
  }
  
  /// 截取字符串
  ///
  /// - Parameter index: 截取从index位开始之前的字符串
  /// - Returns: 返回一个新的字符串
  func mySubString(to index: Int) -> String {
    return String(self[..<self.index(self.startIndex, offsetBy: index)])
  }
  /// 截取字符串
  ///
  /// - Parameter index: 截取从index位开始到末尾的字符串
  /// - Returns: 返回一个新的字符串
  func mySubString(from index: Int) -> String {
    return String(self[self.index(self.startIndex, offsetBy: index)...])
  }
  
  /// 在Swift中URL解码
  ///
  /// - Returns: 在Swift中URL解码
  func  ky_removingPercentEncoding() -> String {
    return self.removingPercentEncoding!
  }
  
  /// 在Swift中URL编码用到的是String的方法
  ///
  /// - Returns:  在Swift中URL编码用到的是String的方法
  func  ky_addingPercentEncoding() -> String {
    
    return self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
  }
  
  /**
   
   *   编码
   
   */
  
  func ky_base64Encoding(plainString:String)->String
    
  {
    
    let plainData = plainString.data(using: String.Encoding.utf8)
    
    let base64String = plainData?.base64EncodedString(options: NSData.Base64EncodingOptions.init(rawValue: 0))
    
    return base64String!
    
  }
  
  
  /**
   
   *   解码
   
   */
  
  func ky_base64Decoding(encodedString:String) -> String
    
  {
    
    let decodedData = NSData(base64Encoded: encodedString, options: NSData.Base64DecodingOptions.init(rawValue: 0))
    let decodedString = NSString(data: decodedData! as Data, encoding: String.Encoding.utf8.rawValue)! as String
    return decodedString
    
  }
  
 
  /// 随机字符串
  ///
  /// - Parameter len: 字符串长度
  /// - Returns: 返回随机字符串
  static func ky_randomStr(len : Int) -> String{
     let random_str_characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    var ranStr = ""
    for _ in 0..<len {
      let index = Int(arc4random_uniform(UInt32(random_str_characters.count)))
      ranStr.append(random_str_characters[random_str_characters.index(random_str_characters.startIndex, offsetBy: index)])
    }
    return ranStr
  }
 
  
  /// 获得当前时间戳的不同格式的字符串
  ///
  /// - Parameter dateFormat: 定制格式 譬如：yyyy年MM月dd日，yyyyMMddHHmmss
  /// - Returns: 返回获得当前时间戳的不同格式的字符串
  static func ky_nowDateToString(dateFormat: String) -> String
  {
        let timeSta: TimeInterval = Date().timeIntervalSince1970
        let dfmatter = DateFormatter()
        dfmatter.dateFormat = dateFormat
        let date = Date(timeIntervalSince1970: timeSta)
        return dfmatter.string(from: date)
  }
  
    /// 字典转Json字符串
    ///
    /// - Parameter dict: 字典
    /// - Returns: 返回字典转Json字符串
    internal  static func ky_dictToJsonStr(dict: [String : Any]) -> String
    {
     
      let data = try? JSONSerialization.data(withJSONObject: dict, options: [])
      let jsonStr = String(data: data!, encoding: String.Encoding.utf8)
      
      return jsonStr!
    }
    
    /// Json字符串字典
    ///
    /// - Parameter jsonStr: Json字符串
    /// - Returns: 返回字典
    internal  static func ky_JsonStrTodict(jsonStr: String) -> [String : Any]
    {
      let jsonData=jsonStr.data(using: String.Encoding.utf8, allowLossyConversion: false)
      let dict = try? JSONSerialization.jsonObject(with: jsonData!, options: .mutableContainers)
    
      return dict! as! [String : Any]
    }
    
    // MARK: - 把秒数转换成时分秒（00:00:00）格式
    ///
    /// - Parameter time: time(Float格式)
    /// - Returns: String格式(00:00:00)
    func ky_transToHourMinSec(time: Float) -> String
    {
        let allTime: Int = Int(time)
        var hours = 0
        var minutes = 0
        var seconds = 0
        var hoursText = ""
        var minutesText = ""
        var secondsText = ""
        
        hours = allTime / 3600
        hoursText = hours > 9 ? "\(hours)" : "0\(hours)"
        
        minutes = allTime % 3600 / 60
        minutesText = minutes > 9 ? "\(minutes)" : "0\(minutes)"
        
        seconds = allTime % 3600 % 60
        secondsText = seconds > 9 ? "\(seconds)" : "0\(seconds)"
        
        return "\(hoursText):\(minutesText):\(secondsText)"
    }

}



